import {
    totalConfig,
    propName
} from 'server/config/templateConfig';
import utils from 'server/core/utils';
import battleHandle from 'server/handle/battleHandle';
let mazesConfig = totalConfig.maze;
let cardsConfig = totalConfig.card;
//地图信息
class MazeModel {
    static getInstance() {
        if (!MazeModel.instance) {
            MazeModel.instance = new MazeModel();
        }
        return MazeModel.instance;
    }

    create(originMazeModel) {
        originMazeModel = originMazeModel || {};
        let mazeId = originMazeModel.mazeId || 180001;
        let data = {
            indexId: originMazeModel.indexId || 1,
            mazeId: mazeId,
            cards: originMazeModel.cards,
            onlyCards: originMazeModel.onlyCards || this.calcOnlyCards(mazeId),
            odds: originMazeModel.odds || this.calcOdds(mazeId)
        }

        if (!originMazeModel.cards) {
            this.mazeReset(data)
        }
        return data;
    }
    calcOdds(mazeId) {
        let odds = mazesConfig[mazeId].zones.odds;
        let data = {};
        for (let [key, value] of Object.entries(odds)) {
            let total = 0;
            value.forEach(item => {
                total += item;
            });
            data[key] = {
                total: total,
                values: value.slice(),
            }
        }
        return data;
    }

    calcOnlyCards(mazeId) {
        let originOnlyCards = mazesConfig[mazeId].zones.onlyCards;
        let onlyCards = originOnlyCards.map(item => {
            return item.slice();
        })
        return onlyCards
    }

    mazeReset(player, mazeInfos) {
        let cards = [];
        mazeInfos.indexId = 1;
        let mazeId = mazeInfos.mazeId;
        mazeInfos.onlyCards = this.calcOnlyCards(mazeId);
        mazeInfos.odds = this.calcOdds(mazeId);
        for (let i = 0; i < 4; i++) {
            let card = this.getCard(player, mazeInfos, true);
            cards.push(card);
        }
        mazeInfos.cards = cards;
    }

    getCard(player, mazeInfos, firstFlag) {
        let mazeId = mazeInfos.mazeId;
        let zonesInfo = mazesConfig[mazeId].zones;
        let odds = mazeInfos.odds;
        let battleMsg;
        if (mazeInfos.indexId > zonesInfo.cardMaxNumber) {
            return null;
        } else if (mazeInfos.indexId === zonesInfo.cardMaxNumber) {
            let monsterId = utils.getOneFromArray(zonesInfo.monsters);
            let card = {
                indexId: mazeInfos.indexId,
                type: 3,
                id: monsterId,
            };
            mazeInfos.indexId += 1;
            return {
                card: card,
                battleMsg: battleMsg
            };
        } else {
            let mainOdds = odds.main;
            let mainRandNumber = Math.random() * mainOdds.total;
            let mainOddsValue = mainOdds.values;
            if (mainRandNumber < mainOddsValue[0]) {
                if (firstFlag !== true) {
                    let randNumber = Math.random() * 100;
                    if (randNumber < 20) {
                        let monsterId = utils.getOneFromArray(zonesInfo.monsters);
                        battleMsg = battleHandle.battle(player, monsterId);
                    }
                }
                let cardsOdds = odds.cards;
                let cardsRandNumber = Math.random() * cardsOdds.total;
                let cardsOddsValue = cardsOdds.values;
                let i = 0;
                while (cardsRandNumber > cardsOddsValue[i]) {
                    cardsRandNumber -= cardsOddsValue[i];
                    i += 1;
                }
              
                let cardId = utils.getOneFromArray(zonesInfo.cards[i]);
                let card = {
                    indexId: mazeInfos.indexId,
                    type: 1,
                    id: cardId,
                };
                mazeInfos.indexId += 1;
                return {
                    card: card,
                    battleMsg: battleMsg
                };
            }
            mainRandNumber -= mainOddsValue[0];
            if (mainRandNumber < mainOddsValue[1]) {
                let onlyCardsOdds = odds.onlyCards;
                let onlyCardsRandNumber = Math.random() * onlyCardsOdds.total;
                let onlyCardsOddsValue = onlyCardsOdds.values;
                let i = 0;
                while (onlyCardsRandNumber > onlyCardsOddsValue[i]) {
                    onlyCardsRandNumber -= onlyCardsOddsValue[i];
                    i += 1;
                }
              
                let cardId = utils.getOneFromArrayAndRemove(mazeInfos.onlyCards[i]);
                if (mazeInfos.onlyCards[i].length === 0) {
                    mazeInfos.onlyCards.splice(i, 1);
                    odds.onlyCards.values.splice(i, 1);
                    let total = 0;
                    odds.onlyCards.values.forEach(item => {
                        total += item;
                    })
                    odds.onlyCards.total = total;
                }
                let card = {
                    indexId: mazeInfos.indexId,
                    type: 1,
                    id: cardId,
                };
                mazeInfos.indexId += 1;
                return {
                    card: card
                };

            }
            mainRandNumber -= mainOddsValue[1];
            if (mainRandNumber < mainOddsValue[2]) {

                let monsterId = utils.getOneFromArray(zonesInfo.monsters);
                let card = {
                    indexId: mazeInfos.indexId,
                    type: 2,
                    id: monsterId,
                };
                mazeInfos.indexId += 1;
                return {
                    card: card,
                    battleMsg: battleMsg
                };
            }
        }

    }

    getMonsterCard(mazeInfos) {
        let mazeId = mazeInfos.mazeId;
        let zoneId = mazeInfos.zoneId;
        let zonesInfo = mazesConfig[mazeId].zones;

        let monsterId = utils.getOneFromArray(zonesInfo.monsters);
        mazeInfos.monsterCardsIndexId += 1;
        let card = {
            indexId: mazeInfos.monsterCardsIndexId,
            type: 2,
            id: monsterId,
        };

        return card;
    }
}

export default MazeModel.getInstance();